<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>Jin Tian</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
  
  <meta name="description" content="Just My Blog">
<meta property="og:type" content="website">
<meta property="og:title" content="Jin Tian">
<meta property="og:url" content="http://yoursite.com/page/4/index.html">
<meta property="og:site_name" content="Jin Tian">
<meta property="og:description" content="Just My Blog">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Jin Tian">
<meta name="twitter:description" content="Just My Blog">
  
    <link rel="alternate" href="/atom.xml" title="Jin Tian" type="application/atom+xml">
  

  

  <link rel="icon" href="/css/images/mylogo.jpg">
  <link rel="apple-touch-icon" href="/css/images/mylogo.jpg">
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link href="https://fonts.googleapis.com/css?family=Open+Sans|Montserrat:700" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic" rel="stylesheet" type="text/css">
  <link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
  <style type="text/css">
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/9749f0/00000000000000000001008f/27/l?subset_id=2&fvd=n5) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/90cf9f/000000000000000000010091/27/l?subset_id=2&fvd=n7) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/8a5494/000000000000000000013365/27/l?subset_id=2&fvd=n4) format("woff2");font-weight:lighter;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/d337d8/000000000000000000010095/27/l?subset_id=2&fvd=i4) format("woff2");font-weight:400;font-style:italic;}</style>
  <link rel="stylesheet" href="/css/style.css">

  <script src="/js/jquery-3.1.1.min.js"></script>
  <script src="/js/bootstrap.js"></script>

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="/css/bootstrap.css" >

  
    <link rel="stylesheet" href="/css/home.css" >
  

  

  

  
  
  
    <link rel="stylesheet" href="/css/vdonate.css" >
  

</head>



  <body>


  
    <header id="header">

	<!-- 背景图模式 -->
	

    
      <div id="intrologo" class="intro-logo">
    
 


    <canvas width="100%" height="100%"></canvas>
    <script>
      var c = document.getElementsByTagName('canvas')[0],
          x = c.getContext('2d'),
          w = window.innerWidth,
          h = window.innerHeight,
          pr = window.devicePixelRatio || 1,
          f = 90,
          q,
          m = Math,
          r = 0,
          u = m.PI*2,
          v = m.cos,
          z = m.random
      c.width = w*pr
      c.height = h*pr
      x.scale(pr, pr)
      x.globalAlpha = 0.6

      <!-- 折线Polyline背景 -->
      
        function i(){
            x.clearRect(0,0,w,h)
            q=[{x:0,y:h*.7+f},{x:0,y:h*.7-f}]
            while(q[1].x<w+f) d(q[0], q[1])
        }
        function d(i,j){   
            x.beginPath()
            x.moveTo(i.x, i.y)
            x.lineTo(j.x, j.y)
            var k = j.x + (z()*2-0.25)*f,
                n = y(j.y)
            x.lineTo(k, n)
            x.closePath()
            r-=u/-50
            x.fillStyle = '#'+(v(r)*127+128<<16 | v(r+u/3)*127+128<<8 | v(r+u/3*2)*127+128).toString(16)
            x.fill()
            q[0] = q[1]
            q[1] = {x:k,y:n}
        }
        function y(p){
            var t = p + (z()*2-1.1)*f
            return (t>h||t<0) ? y(p) : t
        }
        document.getElementById("intrologo").onclick = i
        document.getElementById("intrologo").ontouchstart = i
        i()

      <!-- 多边形trianglify背景 -->
      
    </script>
    

    
      <div id="homelogo" class="homelogo"> 
    

        
          <div class="homelogoback" >
            <h1><a href="#content" id="logo">Jin Tian</a></h1>
            <h3>Just My Blog</h3>
            <h5>Jintian</h5>
            <!-- <p><a href="https://github.com/iTimeTraveler" target="_blank">Github</a></p> -->
          </div>
        
    
    </div>
  </div>

  <!-- 自适应主页背景大图 -->
  

 <!-- home_logo_image居中 -->
 
    <script>
        var homelogodiv = document.getElementById("homelogo");
        if (document.all.homelogo.offsetWidth > document.body.clientWidth) {
          homelogodiv.style.width = document.body.clientWidth + "px";
          homelogodiv.style.marginLeft = document.body.clientWidth * -0.5 + "px";
        } else {
          homelogodiv.style.width = homelogodiv.clientWidth  + "px";
          homelogodiv.style.marginLeft = (homelogodiv.clientWidth)  * -0.5 + "px";
        }
    </script>
  

  <div class="intro-navigate">
      <p class="navigater-list">
        
          <a id="beautifont" class="main-nav-link" href="/">首页</a>
        
          <a id="beautifont" class="main-nav-link" href="/archives">归档</a>
        
          <a id="beautifont" class="main-nav-link" href="/categories">分类</a>
        
          <a id="beautifont" class="main-nav-link" href="/tags">标签</a>
        
          <a id="beautifont" class="main-nav-link" href="/about">关于</a>
        
          <a id="beautifont" class="main-nav-link" href="http://luoli-luoli.com/chat">chat</a>
        
      </p>
  </div>

</header>
  
  <div id="container">
    <div id="wrap">
      
            
      <div id="content" class="outer">
        
          <section id="main" style="float:none;">
  
    <article id="post-黑客从入门到吊炸天系列一-密码生成与黑掉别人的服务器"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/06/07/黑客从入门到吊炸天系列一-密码生成与黑掉别人的服务器/">黑客从入门到吊炸天系列一-密码生成与黑掉别人的服务器</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/06/07/黑客从入门到吊炸天系列一-密码生成与黑掉别人的服务器/" class="article-date">
	  <time datetime="2017-06-07T06:54:39.000Z" itemprop="datePublished">2017-06-07</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>黑客生涯的第一步，这个年代不会一点黑客手段不要意思说自己是神奇夹克。（也许是杰克？？）<br>
        <!-- 黑客生涯的第一步，这个年代不会一点黑客手段不要意思说自己是神奇夹克。（也许是杰克？？）
两位巨星出场，瑞士军刀迈入黑客之旅，手段很重要，两个工具，必备，Hydra, common-password，这两个工具一个是暴力破解工具，不带字典，第二个正式字典生成。但是相信哥，一个8位密码，你如果从0-9a-zA-Z去生成，破解的概率微乎其微。字典起码是7447TB，你懂得，几乎不可能。这个时候就需......  -->
        <p class="article-more-link">
          <a href="/2017/06/07/黑客从入门到吊炸天系列一-密码生成与黑掉别人的服务器/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-C-算法精研系列一"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/06/07/C-算法精研系列一/">C++ 算法精研系列一</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/06/07/C-算法精研系列一/" class="article-date">
	  <time datetime="2017-06-07T04:43:12.000Z" itemprop="datePublished">2017-06-07</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="C-算法精细研究系列"><a href="#C-算法精细研究系列" class="headerlink" title="C++算法精细研究系列"></a>C++算法精细研究系列</h1><h1 id="经典问题一"><a href="#经典问题一" class="headerlink" title="经典问题一"></a>经典问题一</h1><blockquote>
<p>这个问题其实很经典，简而言之，就是一个数组中，有正有负，求取一个和最大的连续子数组。</p>
</blockquote>
<p>这几天在看算法，都得过一遍，但是要领会算法里面的思想，所有代码都用c++实现。首先咋一看这个问题，我们先不管最优算法是如何实现的，直接一顿暴力计算怎么样？<br>思考一下，暴力计算其实很简单，比如我们有数组：<br><figure class="highlight lsl"><table><tr><td class="code"><pre><div class="line">int a[<span class="number">10</span>] = &#123;<span class="number">-1</span>, <span class="number">-2</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">2</span>, <span class="number">-4</span>, <span class="number">2</span>, <span class="number">-1</span>, <span class="number">-9</span>, <span class="number">-3</span>&#125;;</div></pre></td></tr></table></figure></p>
<p>那首先我们要遍历一下数组a，在每一个子循环里面，从i-&gt;a.size,遍历，i-&gt;a.size中的每个j，求取i-&gt;j的子序列和。三个遍历应该就可以把所有情况便利玩。<br>直接上代码了：<br><figure class="highlight cpp"><table><tr><td class="code"><pre><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">findMaxContinueSeq</span><span class="params">(<span class="keyword">int</span>* result, <span class="keyword">int</span> a[], <span class="keyword">int</span> size)</span></span>&#123;</div><div class="line">    <span class="comment">// result, returns the bounds and max sum, size is the a list size</span></div><div class="line"></div><div class="line">    <span class="keyword">int</span> maxSum = <span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> maxStartIndex = <span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> maxEndIndex = <span class="number">0</span>;</div><div class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; ++i) &#123;</div><div class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j &lt; size; ++j) &#123;</div><div class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> k = i; k &lt; j; ++k) &#123;</div><div class="line">                sum += a[k];</div><div class="line">            &#125;</div><div class="line">            <span class="keyword">if</span> (sum &gt; maxSum) maxSum = sum, maxStartIndex = i, maxEndIndex = j<span class="number">-1</span>;</div><div class="line">            sum = <span class="number">0</span>;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"max sum: "</span> &lt;&lt; maxSum &lt;&lt; <span class="built_in">endl</span>;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"max start index: "</span>&lt;&lt; maxStartIndex &lt;&lt; <span class="built_in">endl</span>;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"max end index: "</span>&lt;&lt; maxEndIndex &lt;&lt; <span class="built_in">endl</span>;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>我们设置两个标志位，一个是最大序列的起始一个是终止，起始出现的位置就在当和比暂存器大的时候，把这时候的i记录下来，终止就是j。<br>这个算法起始也很简单的。但是时间复杂度是o(n^3)，因为要遍历三个循环。</p>
<p>接下来我们看一个只需要一次循环就可以解决的算法。<br>这个最优算法，起始道理也是很简单，我就是遍历一次，首先假设一个b=0，每次加一个数，我都用b+a[i],然后我都判断一下，加完之后是大于0还是小于0，<br>如果小于0，那很显然，就抛弃b，把b重置为a[i]从新开始一个序列，加入不小于零，在判断一下b和暂存的最大值大小，如果大，就把暂存最大值更新，小就不管了。<br>这个算法其实用到了呀一个双重保险的思想，即首先添加一个数如果变成了负的，我就终端这个序列，重头开始，如果没有，再判断一下加了之后是变大了还是变小了，如果变大了就更新，没有就保存之前的值，实际上如果没有变大了说明加了一个负数，但是还没有小于零，没有小于零说明还有希望加到一个更大的正数，因此，不到b小于零都不要中断这个序列，一直加下去，实在是小于0了在重置b，开始下一个序列。<br>仔细想一下，这个算法其实，就是基于一个非常简单的假设：<strong>序列有正有负，最大和的序列一定大于零</strong>，既然如此那我就一直加，如果大于就更新不大于继续加，知道小于零就更新序列。<br>代码如下：<br><figure class="highlight cpp"><table><tr><td class="code"><pre><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">findMaxContinueSeqOptimal</span><span class="params">(<span class="keyword">int</span>* result, <span class="keyword">int</span> a[], <span class="keyword">int</span> size)</span></span>&#123;</div><div class="line"></div><div class="line">    <span class="comment">//算法思想很简单，首先最大值一定大于0，那么每次加一下下一个元素，我就</span></div><div class="line">    <span class="comment">//判断一下，上一个和，如果小于零则直接把b重置，否则加上下一个元素</span></div><div class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> b=<span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> maxStartIndex = <span class="number">0</span>;</div><div class="line">    <span class="keyword">int</span> maxEndIndex = <span class="number">0</span>;</div><div class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; ++i) &#123;</div><div class="line">        <span class="keyword">if</span> (b&lt;<span class="number">0</span>)&#123;</div><div class="line">            b = a[i];</div><div class="line">            maxStartIndex = i;</div><div class="line">        &#125; <span class="keyword">else</span>&#123;</div><div class="line">            b += a[i];</div><div class="line">        &#125;</div><div class="line"></div><div class="line">        <span class="keyword">if</span> (b&gt;sum)&#123;</div><div class="line">            sum = b;</div><div class="line">            maxEndIndex = i;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"optimal max sum: "</span> &lt;&lt; sum &lt;&lt; <span class="built_in">endl</span>;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"max start index: "</span>&lt;&lt; maxStartIndex &lt;&lt; <span class="built_in">endl</span>;</div><div class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"max end index: "</span>&lt;&lt; maxEndIndex &lt;&lt; <span class="built_in">endl</span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>最后我们调用代码来测试一下：<br><figure class="highlight lsl"><table><tr><td class="code"><pre><div class="line">int main() &#123;</div><div class="line">    int a[<span class="number">10</span>] = &#123;<span class="number">-1</span>, <span class="number">-2</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">2</span>, <span class="number">-4</span>, <span class="number">2</span>, <span class="number">-1</span>, <span class="number">-9</span>, <span class="number">-3</span>&#125;;</div><div class="line">    int b;</div><div class="line"></div><div class="line">    findMaxContinueSeq(a, a, <span class="number">10</span>);</div><div class="line">    findMaxContinueSeqOptimal(a, a, <span class="number">10</span>);</div><div class="line"></div><div class="line">    return <span class="number">0</span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>两个函数返回的结果是一致的。</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-50行代码实现GAN系列-PyTorch"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/29/50行代码实现GAN系列-PyTorch/">50行代码实现GAN系列-PyTorch</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/29/50行代码实现GAN系列-PyTorch/" class="article-date">
	  <time datetime="2017-05-29T09:16:22.000Z" itemprop="datePublished">2017-05-29</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <blockquote>
<p>人生苦短我用GAN</p>
</blockquote>
<p>首先声明一下，本教程面向入门吃瓜群众，大牛可以绕道，闲话不多说，先方一波广告。（高级GAN玩法），怎么说，我越来越感觉到人工智能正在迎来生成模型的时代，以前海量数据训练模型的办法有点揠苗助长，看似效果很好，实际上机器什么卵都没有学到（至少从迁移性上看缺少一点味道，不过就图片领域来说另当别论，在CV领域监督学习还是相当成功）。<br>但是问题来了，GAN这么屌这么牛逼，我怎么搞？怎么入门？谁带我？慌了！</p>
<h1 id="莫慌，50行代码你就可以成为无监督学习大牛"><a href="#莫慌，50行代码你就可以成为无监督学习大牛" class="headerlink" title="莫慌，50行代码你就可以成为无监督学习大牛"></a>莫慌，50行代码你就可以成为无监督学习大牛</h1><p>我最讨厌那些，嘴里一堆算法，算法实现不出来的人。因为我喜欢看到结果啊！尤其是一些教程，就是将论文，鸡巴论文奖那么多有什么用？你码代码给我看啊，我不知道数据是什么，不知道输入维度是什么，输出什么，里面到底发生了什么变化我怎么学？这就有点像，典型的在沙漠里教你钓鱼，在我看来，论文应该是最后才去看的东西。但是问题在于，你要有一个入门的教程啊。我想这是一个鸿沟，科研里面，理论和动手的鸿沟。<br>这篇教程就是引路人了。欢迎加入生成模型队伍。这个教程<strong>会一直保持更新</strong>，因为科技每天变幻莫测，同时我还会加入很多新内容，改进一些在以后看来是错误的说法。</p>
<p>首先，我们废话不多说了，直接show you the code：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> torch</div><div class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</div><div class="line"><span class="keyword">import</span> torch.nn.functional <span class="keyword">as</span> F</div><div class="line"><span class="keyword">from</span> torch.autograd <span class="keyword">import</span> Variable</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> stats</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">generate_real_data_distribution</span><span class="params">(n_dim, num_samples)</span>:</span></div><div class="line">    all_data = []</div><div class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(num_samples):</div><div class="line">        x = np.random.uniform(<span class="number">0</span>, <span class="number">8</span>, n_dim)</div><div class="line">        y = stats.lognorm.pdf(x, <span class="number">0.6</span>)</div><div class="line">        all_data.append(y)</div><div class="line">    all_data = np.array(all_data)</div><div class="line">    print(<span class="string">'generated data shape: '</span>, all_data.shape)</div><div class="line">    <span class="keyword">return</span> all_data</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">batch_inputs</span><span class="params">(all_data, batch_size=<span class="number">6</span>)</span>:</span></div><div class="line">    <span class="keyword">assert</span> isinstance(all_data, np.ndarray), <span class="string">'all_data must be numpy array'</span></div><div class="line">    batch_x = all_data[np.random.randint(all_data.shape[<span class="number">0</span>], size=batch_size)]</div><div class="line">    <span class="keyword">return</span> Variable(torch.from_numpy(batch_x).float())</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></div><div class="line">    <span class="comment"># 给generator的噪音维数</span></div><div class="line">    n_noise_dim = <span class="number">30</span></div><div class="line">    <span class="comment"># 真实数据的维度</span></div><div class="line">    n_real_data_dim = <span class="number">256</span></div><div class="line">    num_samples = <span class="number">666</span></div><div class="line">    lr_g = <span class="number">0.001</span></div><div class="line">    lr_d = <span class="number">0.03</span></div><div class="line">    batch_size = <span class="number">6</span></div><div class="line">    epochs = <span class="number">1000</span></div><div class="line"></div><div class="line">    real_data = generate_real_data_distribution(n_real_data_dim, num_samples=num_samples)</div><div class="line">    print(<span class="string">'sample from real data: \n'</span>, real_data[: <span class="number">10</span>])</div><div class="line"></div><div class="line">    g_net = nn.Sequential(</div><div class="line">        nn.Linear(n_noise_dim, <span class="number">128</span>),</div><div class="line">        nn.ReLU(),</div><div class="line">        nn.Linear(<span class="number">128</span>, n_real_data_dim)</div><div class="line">    )</div><div class="line"></div><div class="line">    d_net = nn.Sequential(</div><div class="line">        nn.Linear(n_real_data_dim, <span class="number">128</span>),</div><div class="line">        nn.ReLU(),</div><div class="line">        nn.Linear(<span class="number">128</span>, <span class="number">1</span>),</div><div class="line">        nn.Sigmoid()</div><div class="line">    )</div><div class="line"></div><div class="line">    opt_d = torch.optim.Adam(d_net.parameters(), lr=lr_d)</div><div class="line">    opt_g = torch.optim.Adam(g_net.parameters(), lr=lr_g)</div><div class="line"></div><div class="line">    <span class="keyword">for</span> epoch <span class="keyword">in</span> range(epochs):</div><div class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> range(num_samples // batch_size):</div><div class="line">            batch_x = batch_inputs(real_data, batch_size)</div><div class="line">            batch_noise = Variable(torch.randn(batch_size, n_noise_dim))</div><div class="line"></div><div class="line">            g_data = g_net(batch_noise)</div><div class="line"></div><div class="line">            <span class="comment"># 用G判断两个输出分别多大概率是来自真正的画家</span></div><div class="line">            prob_fake = d_net(g_data)</div><div class="line">            prob_real = d_net(batch_x)</div><div class="line"></div><div class="line">            <span class="comment"># 很显然，mean里面的这部分是一个负值，如果想整体loss变小，必须要变成正直，加一个负号，否则会越来越大</span></div><div class="line">            d_loss = -torch.mean(torch.log(prob_real) + torch.log(<span class="number">1</span> - prob_fake))</div><div class="line">            <span class="comment"># 而g的loss要使得discriminator的prob_fake尽可能小，这样才能骗过它，因此也要加一个负号</span></div><div class="line">            g_loss = -torch.mean(torch.log(prob_fake))</div><div class="line"></div><div class="line">            opt_d.zero_grad()</div><div class="line">            d_loss.backward(retain_variables=<span class="keyword">True</span>)</div><div class="line">            opt_d.step()</div><div class="line"></div><div class="line">            opt_g.zero_grad()</div><div class="line">            g_loss.backward(retain_variables=<span class="keyword">True</span>)</div><div class="line">            opt_g.step()</div><div class="line"></div><div class="line">            print(<span class="string">'Epoch: &#123;&#125;, batch: &#123;&#125;, d_loss: &#123;&#125;, g_loss: &#123;&#125;'</span>.format(epoch, i, d_loss.data.numpy()[<span class="number">0</span>],</div><div class="line">                                                                        g_loss.data.numpy()[<span class="number">0</span>]))</div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    main()</div></pre></td></tr></table></figure>
<p>这些代码，总共，也就是90行，核心代码50行，基本上，比你写一个其他程序都端，什么红黑算法，什么排序之类的。我个人比较喜欢简约，我很多时候不喜欢太鸡巴隆昌的代码。</p>
<h1 id="直接开始训练吧"><a href="#直接开始训练吧" class="headerlink" title="直接开始训练吧"></a>直接开始训练吧</h1><p>这个GAN很简单，三部分：</p>
<ul>
<li>real data生成，这个real data我们怎么去模拟呢？注意这里用的数据是二维的，不是图片，图片是三维的，二维你可以看成是csv，或者是序列，在这里面我们每一行，也就是一个样本，是sample自某个分布的数据，这里用的分布式lognorm；</li>
<li>d_net 和 g_net，这里两个net都是非常小，小到爆炸，这如果要是用tensorflow写就有点蛋疼了，我选择PyTorch，一目了然；</li>
<li>loss，loss在GAN中非常重要，是接下来的重点。</li>
</ul>
<p>OK，一阵复制粘贴，你就可以训练一个GAN，这个GAN用来做什么？就是你随机输入一个噪音，生成模型将会生成一个和lognorm分布一样的数据。也就是说，生成模型学到了lognrom分布。这能说明什么？神经网络学到了概率！用到图片里面就是，他知道哪个颜色快可能是什么东西，这也是现在的CycleGAN， DiscoGAN的原理。</p>
<h1 id="我吃饭去了"><a href="#我吃饭去了" class="headerlink" title="我吃饭去了"></a>我吃饭去了</h1><p>未完待续…</p>
<h1 id="来了"><a href="#来了" class="headerlink" title="来了"></a>来了</h1><p>继续刚才的，好像我写的文章没有人看啊，伤感。自己写自己看吧，哎，我骚味改了一下代码，loss函数部分，之前的写错了，我偷一张图把。<br><img src="http://wiseodd.github.io/img/2016-09-17-gan-tensorflow/algorithm.png" alt=""><br>这个是公式，原始GAN论文里面给的公式，但是毫无疑问，正如很多人说的那样，GAN很容易漂移：</p>
<figure class="highlight groovy"><table><tr><td class="code"><pre><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">66</span>, <span class="string">d_loss:</span> <span class="number">0.7026655673980713</span>, <span class="string">g_loss:</span> <span class="number">2.0336945056915283</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">67</span>, <span class="string">d_loss:</span> <span class="number">0.41225430369377136</span>, <span class="string">g_loss:</span> <span class="number">2.1994106769561768</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">68</span>, <span class="string">d_loss:</span> <span class="number">0.674636960029602</span>, <span class="string">g_loss:</span> <span class="number">1.5774009227752686</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">69</span>, <span class="string">d_loss:</span> <span class="number">0.5779278874397278</span>, <span class="string">g_loss:</span> <span class="number">2.2797725200653076</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">70</span>, <span class="string">d_loss:</span> <span class="number">0.4029145836830139</span>, <span class="string">g_loss:</span> <span class="number">2.200833559036255</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">71</span>, <span class="string">d_loss:</span> <span class="number">0.7264774441719055</span>, <span class="string">g_loss:</span> <span class="number">1.5658557415008545</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">72</span>, <span class="string">d_loss:</span> <span class="number">0.46858924627304077</span>, <span class="string">g_loss:</span> <span class="number">2.355680227279663</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">73</span>, <span class="string">d_loss:</span> <span class="number">0.6716371774673462</span>, <span class="string">g_loss:</span> <span class="number">1.7127293348312378</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">74</span>, <span class="string">d_loss:</span> <span class="number">0.7237206101417542</span>, <span class="string">g_loss:</span> <span class="number">1.4458404779434204</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">75</span>, <span class="string">d_loss:</span> <span class="number">0.9684935212135315</span>, <span class="string">g_loss:</span> <span class="number">1.943861961364746</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">76</span>, <span class="string">d_loss:</span> <span class="number">0.4705852270126343</span>, <span class="string">g_loss:</span> <span class="number">2.439894199371338</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">77</span>, <span class="string">d_loss:</span> <span class="number">0.4989328980445862</span>, <span class="string">g_loss:</span> <span class="number">1.5290288925170898</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">78</span>, <span class="string">d_loss:</span> <span class="number">0.44530192017555237</span>, <span class="string">g_loss:</span> <span class="number">2.9254989624023438</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">79</span>, <span class="string">d_loss:</span> <span class="number">0.6329593658447266</span>, <span class="string">g_loss:</span> <span class="number">1.7527830600738525</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">80</span>, <span class="string">d_loss:</span> <span class="number">0.42348209023475647</span>, <span class="string">g_loss:</span> <span class="number">1.856258749961853</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">81</span>, <span class="string">d_loss:</span> <span class="number">0.5396828651428223</span>, <span class="string">g_loss:</span> <span class="number">2.268836498260498</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">82</span>, <span class="string">d_loss:</span> <span class="number">0.9727945923805237</span>, <span class="string">g_loss:</span> <span class="number">1.0528483390808105</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">83</span>, <span class="string">d_loss:</span> <span class="number">0.7551510334014893</span>, <span class="string">g_loss:</span> <span class="number">1.508225917816162</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">84</span>, <span class="string">d_loss:</span> <span class="number">2.4204068183898926</span>, <span class="string">g_loss:</span> <span class="number">1.5375216007232666</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">85</span>, <span class="string">d_loss:</span> <span class="number">1.517686128616333</span>, <span class="string">g_loss:</span> <span class="number">0.6334291100502014</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">86</span>, <span class="string">d_loss:</span> inf, <span class="string">g_loss:</span> <span class="number">0.7990849614143372</span></div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">87</span>, <span class="string">d_loss:</span> nan, <span class="string">g_loss:</span> nan</div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">88</span>, <span class="string">d_loss:</span> nan, <span class="string">g_loss:</span> nan</div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">89</span>, <span class="string">d_loss:</span> nan, <span class="string">g_loss:</span> nan</div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">90</span>, <span class="string">d_loss:</span> nan, <span class="string">g_loss:</span> nan</div><div class="line"><span class="string">Epoch:</span> <span class="number">47</span>, <span class="string">batch:</span> <span class="number">91</span>, <span class="string">d_loss:</span> nan, <span class="string">g_loss:</span> nan</div></pre></td></tr></table></figure>
<p>你如果train一下的话会发现，到一定程度就会nan，这个nan我就无法理解了，按道理来说，从loss来看我们定义的来自以log，如果为无穷那么应该是log(0)了，但是我们的discriminator出来的函数是sigmoid啊，sigmoid不可能为0，只看是0-1且不包括闭区间。这个问题比较玄学。</p>
<p>既然nan的话，我也不深究是因为啥了，总之这个重点在于loss，因为后面GAN的变种基本上都是在loss的训练形式上。</p>
<h1 id="GAN-生成mnist"><a href="#GAN-生成mnist" class="headerlink" title="GAN 生成mnist"></a>GAN 生成mnist</h1><p>我们现在玩一下mnist把。</p>
<h1 id="交流"><a href="#交流" class="headerlink" title="交流"></a>交流</h1><p>我见了一个GAN群，加我微信让我拉进来。jintianiloveu, 顺便下载一个我做的app吧，内侧中，专门用来看美女图片的，你懂得。。<a href="http://www.jianshu.com/p/01e41d143e21" target="_blank" rel="noopener">传送门</a></p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-萝莉萝莉1-0-2版本发布"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/29/萝莉萝莉1-0-2版本发布/">萝莉萝莉1.0.2版本发布</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/29/萝莉萝莉1-0-2版本发布/" class="article-date">
	  <time datetime="2017-05-29T04:48:28.000Z" itemprop="datePublished">2017-05-29</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>萝莉萝莉分布，定时更新新版本，你要的女神萝莉这里全都有。<br>
        <!-- 萝莉萝莉分布，定时更新新版本，你要的女神萝莉这里全都有。

一个文艺又猥琐的小APP

萝莉萝莉你值得把玩且不说萝莉萝莉的设计，但就功能来说，倒数日绝对精美，大家可以感受一下：


通过萝莉萝莉，大家可以记录自己最期待的日子
除了倒数日，我们依旧可以通过萝莉萝莉获取到一些有意思的资讯，比如来自知乎日报：
最后，是来自我们的福利:
萝莉萝莉从动工以来，就一直想努力实现这么一个目标：

做一个设......  -->
        <p class="article-more-link">
          <a href="/2017/05/29/萝莉萝莉1-0-2版本发布/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-无监督学习笔记-1-Variational-Autoencoder-and-Adversarial-Autoencoder"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/24/无监督学习笔记-1-Variational-Autoencoder-and-Adversarial-Autoencoder/">无监督学习笔记 1: Variational Autoencoder and Adversarial Autoencoder</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/24/无监督学习笔记-1-Variational-Autoencoder-and-Adversarial-Autoencoder/" class="article-date">
	  <time datetime="2017-05-24T03:24:25.000Z" itemprop="datePublished">2017-05-24</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>无监督学习第一坑<br>
        <!-- 无监督学习第一坑


是时候沉下心来学习理论了，前端时间一直沉迷于写代码，后来发现，代码其实是个坑，只要自动精通了，别人写的1000行的代码老子用10行实现他。

首先请允许我用一张图来代表一下生成对抗的思想：

VAE 简介VAE中文翻译叫啥，变分自动编码机？可以这么说把。其实在很久以前，我们就知道有Autoencoder这个东西，比如SparseAutoencoder，DenisingA......  -->
        <p class="article-more-link">
          <a href="/2017/05/24/无监督学习笔记-1-Variational-Autoencoder-and-Adversarial-Autoencoder/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-上天的步骤"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/23/上天的步骤/">上天的步骤</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/23/上天的步骤/" class="article-date">
	  <time datetime="2017-05-23T01:02:16.000Z" itemprop="datePublished">2017-05-23</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>本文简要记录一下上天的步骤<br>
        <!-- 本文简要记录一下上天的步骤
首先是相关依赖的安装直接clone我的一件安装脚本，基本上所有软件都安装就绪。
设置nginxnginx设置最简单的就是http只写80端口，如果是https的话除了服务器的防火墙比较蛋疼外，还要加上证书，证书也得加载nginx里面，除了nginx，django的服务器也要加载证书，比较蛋疼。 一步一步测试可以先改nginx，然后django启动自带的简单服务器，......  -->
        <p class="article-more-link">
          <a href="/2017/05/23/上天的步骤/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-PocketSphinx-人工智能第二步-语音识别库的安装和使用"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/17/PocketSphinx-人工智能第二步-语音识别库的安装和使用/">PocketSphinx 人工智能第二步-语音识别库的安装和使用</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/17/PocketSphinx-人工智能第二步-语音识别库的安装和使用/" class="article-date">
	  <time datetime="2017-05-17T01:32:53.000Z" itemprop="datePublished">2017-05-17</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>本文介绍语音识别神器pocketsphinx的使用<br>
        <!-- 本文介绍语音识别神器pocketsphinx的使用
PocketSphinx介绍其实对于一个语音小白来说，去探索一些比较牛逼的库的其实是很盲目的，好在我在全球最大的男同交友网站遇到了一个大神，大神告诉我pocketsphinx是他的神器，我说可以的，于是我就谷歌了一下，发现还真的有这么个牛逼闪闪的东西。这几把集成到Jarvis里面不就实现了语音控制了吗？？？还等什么，赶紧安装一波！！
Poc......  -->
        <p class="article-more-link">
          <a href="/2017/05/17/PocketSphinx-人工智能第二步-语音识别库的安装和使用/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-Reinforcement-从入门到上天Series-1"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/05/08/Reinforcement-从入门到上天Series-1/">ReinforcementLearning从入门到上天Series 1</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/05/08/Reinforcement-从入门到上天Series-1/" class="article-date">
	  <time datetime="2017-05-08T07:57:14.000Z" itemprop="datePublished">2017-05-08</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>是时候入坑强化学习了，得整出点名堂出来。<br>
        <!-- 是时候入坑强化学习了，得整出点名堂出来。
入门其实不管是深度学习框架还是算法，自己动手去实现一些实验很重要，更重要的是得了解当下最流行的东西是什么。我感觉强化学习如果再不跟上就可能落伍时代了，毕竟强化学习和深度学习可以说是另一个新天地。
Agent, Actions, Environments, Observations, Reward, StateObservations上面应该就是强化学......  -->
        <p class="article-more-link">
          <a href="/2017/05/08/Reinforcement-从入门到上天Series-1/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/强化学习/">强化学习</a></li></ul>

    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-Python多线程再研究"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/04/28/Python多线程再研究/">Python多线程再研究</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/04/28/Python多线程再研究/" class="article-date">
	  <time datetime="2017-04-28T01:22:39.000Z" itemprop="datePublished">2017-04-28</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="继上一篇多线程文章之后，继续研究Python多线程并发"><a href="#继上一篇多线程文章之后，继续研究Python多线程并发" class="headerlink" title="继上一篇多线程文章之后，继续研究Python多线程并发"></a>继上一篇多线程文章之后，继续研究Python多线程并发</h1><blockquote>
<p>多线程在创作大型程序的过程中显得尤为重要，在开发Jarvis的过程中，我一直找不到一个合适的方法去让他在不妨碍主线程的情况之下去执行任意程序。实际上这就完全可以用多线程来解决，听起来非常简单，但实际上不然。真正做起来还是有点麻烦。这篇文章我们将继续梳理python多线程</p>
</blockquote>
<h1 id="抛弃multiporcess使用Threading"><a href="#抛弃multiporcess使用Threading" class="headerlink" title="抛弃multiporcess使用Threading"></a>抛弃multiporcess使用Threading</h1><p>上一篇文章中我讲到了multiprocess这个pyton官方模块，但是这个模块并不好用，不够友好，我们决定使用Threading，Threading看上去更简单，使用方法也和multiprocess一样，threading创建多个线程，然后一一回收，最后甚至可以用一种非常简单的方法回收每个线程的返回值。我直接贴代码如下：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"><span class="keyword">import</span> threading</div><div class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</div><div class="line"><span class="keyword">import</span> time</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> logging</div><div class="line"></div><div class="line">logging.basicConfig(level=logging.DEBUG, format=<span class="string">'(%(threadName)-10s) %(message)s'</span>)</div><div class="line"></div><div class="line">r = []</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">worker</span><span class="params">(i_, w_)</span>:</span></div><div class="line">    c = <span class="number">0</span></div><div class="line">    p = np.random.randint(<span class="number">0</span>, <span class="number">10</span>)</div><div class="line">    <span class="keyword">while</span> <span class="keyword">True</span>:</div><div class="line">        logging.info(<span class="string">'hello, &#123;&#125;. worker &#123;&#125; now time: &#123;&#125;'</span>.format(w_, i_, datetime.now()))</div><div class="line">        time.sleep(<span class="number">2</span>)</div><div class="line">        c += <span class="number">1</span></div><div class="line">        <span class="keyword">if</span> c &gt; p:</div><div class="line">            <span class="keyword">break</span></div><div class="line">    r.append(p)</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    threads = []</div><div class="line">    w = [<span class="string">'fuck'</span>, <span class="string">'stupid'</span>, <span class="string">'what are u dong'</span>, <span class="string">'go die'</span>, <span class="string">'god damn it.'</span>]</div><div class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</div><div class="line">        t = threading.Thread(target=worker, args=(i, w[i]))</div><div class="line">        threads.append(t)</div><div class="line">        t.start()</div><div class="line">    <span class="keyword">for</span> t <span class="keyword">in</span> threads:</div><div class="line">        t.join()</div><div class="line">    print(<span class="string">'[last]'</span>)</div><div class="line">    print(r)</div></pre></td></tr></table></figure>
<p>在这个例子中，我们有5个线程，每个线程执行worker里面的函数，但是有中断的条件就是随机一个10以内的数，当循环大于这个数的时候，我们就break。<br>大家运行就会看到，我把所有线程都join到回收池，也就意味着所有线程都执行完了，然后我使用了一个r数组来收集每个线程的返回值，简单吧。</p>
<p>最后就可以直接打印出，每个函数的随机停止的值是多少。</p>
<h1 id="Threading还能干什么"><a href="#Threading还能干什么" class="headerlink" title="Threading还能干什么"></a>Threading还能干什么</h1><p>在上面的例子中，如果我们在实现这么一个多线程的例子：</p>
<blockquote>
<p>有一个主线程，任务是执行print hello，然后在时间到了一分钟之后这个时间点时候就分开一个线程去print ‘我要看黄色笑话’，但是依旧不妨碍主线程的运行，那这个时候我们能不能做到呢？</p>
</blockquote>
<p>事实上完全可以的，我直接贴出我们的例子代码：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</div><div class="line"><span class="keyword">import</span> logging</div><div class="line"><span class="keyword">import</span> time</div><div class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</div><div class="line"></div><div class="line">logging.basicConfig(level=logging.DEBUG, format=<span class="string">'(%(threadName)-10s) %(message)s'</span>)</div><div class="line"></div><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">CruiseBot</span><span class="params">(object)</span>:</span></div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></div><div class="line">        self.name = <span class="string">'Cruise'</span></div><div class="line"></div><div class="line">        self._init_start_time()</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">cruise</span><span class="params">(self)</span>:</span></div><div class="line">        self._main_loop()</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_init_start_time</span><span class="params">(self)</span>:</span></div><div class="line">        self.start_time = datetime.now().minute</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_main_loop</span><span class="params">(self)</span>:</span></div><div class="line">        <span class="comment"># this is his main duty job</span></div><div class="line">        <span class="keyword">while</span> <span class="keyword">True</span>:</div><div class="line">            logging.debug(<span class="string">'hello, I am &#123;&#125;, now time is: &#123;&#125;'</span>.format(self.name, datetime.now()))</div><div class="line">            time.sleep(<span class="number">5</span>)</div><div class="line"></div><div class="line">            now = datetime.now().minute</div><div class="line">            <span class="keyword">if</span> now - self.start_time == <span class="number">1</span>:</div><div class="line">                <span class="comment"># 1分钟之后开一个线程执行另外一个事情</span></div><div class="line">                logging.debug(<span class="string">'start execute job 1'</span>)</div><div class="line">                t = Thread(name=<span class="string">'alice'</span>, target=self._thread_job_1, args=(<span class="number">1</span>,))</div><div class="line">                t.start()</div><div class="line">            <span class="keyword">if</span> now - self.start_time == <span class="number">2</span>:</div><div class="line">                <span class="comment"># 2分钟之后开一个线程执行另外一个事情</span></div><div class="line">                logging.debug(<span class="string">'start execute job 2'</span>)</div><div class="line">                t = Thread(name=<span class="string">'bob'</span>, target=self._thread_job_2, args=(<span class="number">2</span>,))</div><div class="line">                t.start()</div><div class="line"></div><div class="line"><span class="meta">    @staticmethod</span></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_thread_job_1</span><span class="params">(i)</span>:</span></div><div class="line">        <span class="keyword">while</span> <span class="keyword">True</span>:</div><div class="line">            logging.debug(<span class="string">'thread jobber &#123;&#125;, i am eating hamburg!!!!'</span>.format(i))</div><div class="line">            time.sleep(<span class="number">2</span>)</div><div class="line"></div><div class="line"><span class="meta">    @staticmethod</span></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_thread_job_2</span><span class="params">(i)</span>:</span></div><div class="line">        <span class="keyword">while</span> <span class="keyword">True</span>:</div><div class="line">            logging.debug(<span class="string">'thread jobber &#123;&#125;, i am doing say hello'</span>.format(i))</div><div class="line">            time.sleep(<span class="number">2</span>)</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></div><div class="line">    cruise_bot = CruiseBot()</div><div class="line">    cruise_bot.cruise()</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    main()</div></pre></td></tr></table></figure>
<p>这个代码有点长，实际上我们只需要关注定义的那个巡航机器人类，在这里祝循环里面它要做一个事情，然后在一分钟后执行第一个子任务，两分钟后执行第二个子任务，可以看到，在这里我们的设定的工作完全执行正常，整个程序从第二分钟开始指定第二个子任务，并且并没有妨碍主线程的执行。这正是我们想要的。</p>
<h1 id="进一步思考"><a href="#进一步思考" class="headerlink" title="进一步思考"></a>进一步思考</h1><p>教程写到这里，我就得进一步思考怎么给Jarvis添加分身的大脑了。Jarvis要实现的功能是当接收到某个指令时，这个指令是让他在某个时间去执行某个事情，怎么才能实现，给他添加一个reminder，当到了那个时间后他就去执行那个事情呢？</p>
<p>首先，让我们来捋一下思路。首先在某个时间干某件事情，某个时间好办，我可以这样，我命令说9点帮我发消息给安安，那么我可以让Jarvis把9点这个时间记录下来，然后从开始运行到结束，一直开一个线程去遍历本地的todo事件，并且对比这个todo时间的执行time跟当前时间的差，如果跟当前时间差了差不多2分钟（注意这里的两分钟指的是这个线程的呼吸时间，这个时间不能太快，太快会把机器类似），我们就执行这个事件。</p>
<p>刚才吃饭去了，ok我们继续写，刚才说到我们可以在接收到指令之后就把这个时间存入本地文件里面，然后有一个巡航的线程会一直去读取然后查询是否有事件，如果满足执行时间要求就执行这个时间，那么问题来了，这个时间是存入数据库好呢还是存入pickle文件好呢，实际上我感觉都一样，考虑到便利应该存入pickel文件更好一些，不不不不，错了错了，还是存入数据库好一点，用mongo存的话，那么每个时间就有一个时间属性，一个名称，重点是名称，这个名称不仅仅是单一的时间名称还可以是一个数组包含多个字段，方便后面Jarvis进行模糊查询，除此之外这个todo collection的doc中还要包含event subject和event receptor，为什么要设计这个，是因为Jarvis做的每一个事情都应该有一个时间的主体和受体，试想一下，有木有时间不存在主体和受体呢？好吧其实这个设计的也没有什么用。但是数据库中以下结构是必须要的：</p>
<figure class="highlight ceylon"><table><tr><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="string">'todo_event_name'</span>: [<span class="string">'给安安打电话'</span>, <span class="string">'打电话给安安'</span>],</div><div class="line">  <span class="string">'todo_event_executor'</span>: <span class="string">'command.phone'</span>,</div><div class="line">  <span class="string">'todo_event_time'</span>: datetime.datime&lt;<span class="keyword">object</span>&gt;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>ok,现在感觉todo时间的存储问题解决了，直接存入mongo，然后开启一个线程每隔两分钟查询一次数据库把当前时间的事件都列出来然后一一去执行。感觉问题解决了有木有，但是问题又来了，怎么把一个函数存入数据库呢？上面写的按照注册名来写其实是不科学的，应该获取不到。接下来我们要做一个实验了。</p>
<blockquote>
<p>我们依旧从上面的巡航机器人代码的开始改，这次要实现的功能是，我过了一分钟之后就把一个代执行的函数存入pkl中，同时存入参数，表示我当前接收到了一个命令然后把命令的执行方法保存下来，在到了执行之间之后再调用它去执行。</p>
</blockquote>
<p>ok,到这里我们的问题已经解决了。我们现在是这样的：所有todo的事件保存到pkl之中，方法只要保存类名和方法名即可，使用Python里面的发射和自省来实现根据类名调用函数。这样的话我开启一个线程不断的读取那个文件，注意为了保证不锁死线程，我们偶数分钟的时候去读取，奇数分钟的时候去存。最后就可以在任意适合牛逼的调用任何方法了！！！！！<br>贴出这个实验代码：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</div><div class="line"><span class="keyword">import</span> logging</div><div class="line"><span class="keyword">import</span> time</div><div class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</div><div class="line"><span class="keyword">import</span> pickle</div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">from</span> todo.todo <span class="keyword">import</span> ToDoer</div><div class="line"></div><div class="line">logging.basicConfig(level=logging.DEBUG, format=<span class="string">'(%(threadName)-10s) %(message)s'</span>)</div><div class="line"></div><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">CruiseBot</span><span class="params">(object)</span>:</span></div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></div><div class="line">        self.name = <span class="string">'Cruise'</span></div><div class="line"></div><div class="line">        self._init_start_time()</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">cruise</span><span class="params">(self)</span>:</span></div><div class="line">        self._main_loop()</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_init_start_time</span><span class="params">(self)</span>:</span></div><div class="line">        self.start_time = datetime.now()</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_main_loop</span><span class="params">(self)</span>:</span></div><div class="line">        <span class="comment"># this is his main duty job</span></div><div class="line">        threads = []</div><div class="line">        <span class="keyword">while</span> <span class="keyword">True</span>:</div><div class="line">            logging.debug(<span class="string">'&#123;&#125;, now time is: &#123;&#125;'</span>.format(self.name, datetime.now()))</div><div class="line">            time.sleep(<span class="number">5</span>)</div><div class="line"></div><div class="line">            now = datetime.now()</div><div class="line">            delta = (now - self.start_time).seconds</div><div class="line">            print(<span class="string">'delta '</span>, delta)</div><div class="line">            <span class="keyword">if</span> delta == <span class="number">10</span>:</div><div class="line">                <span class="comment"># 10s之后开一个线程执行另外一个事情</span></div><div class="line">                logging.debug(<span class="string">'start execute job 2'</span>)</div><div class="line">                t2 = Thread(name=<span class="string">'bob'</span>, target=self._thread_job_1)</div><div class="line">                t2.start()</div><div class="line">                threads.append(t2)</div><div class="line">            <span class="keyword">if</span> delta == <span class="number">20</span>:</div><div class="line">                <span class="comment"># 20s之后开一个线程执行另外一个事情</span></div><div class="line">                logging.debug(<span class="string">'start execute job 2'</span>)</div><div class="line">                t3 = Thread(name=<span class="string">'cc'</span>, target=self._thread_job_2)</div><div class="line">                t3.start()</div><div class="line">                threads.append(t3)</div><div class="line">            <span class="keyword">if</span> delta == <span class="number">30</span>:</div><div class="line">                <span class="keyword">for</span> t <span class="keyword">in</span> threads:</div><div class="line">                    t.join()</div><div class="line">                <span class="keyword">break</span></div><div class="line"></div><div class="line"><span class="meta">    @staticmethod</span></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_thread_job_1</span><span class="params">()</span>:</span></div><div class="line">        obj = &#123;</div><div class="line">            <span class="string">'class_name'</span>: <span class="string">'ToDoer'</span>,</div><div class="line">            <span class="string">'function_name'</span>: <span class="string">'todo_job'</span>,</div><div class="line">            <span class="string">'function_args'</span>: ([<span class="string">'hello'</span>, <span class="string">'fuck'</span>, <span class="string">'shit'</span>, <span class="string">'man'</span>],),</div><div class="line">            <span class="string">'time'</span>: datetime.now()</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">with</span> open(<span class="string">'todo.pkl'</span>, <span class="string">'wb'</span>) <span class="keyword">as</span> f:</div><div class="line">            pickle.dump(obj, f)</div><div class="line">        logging.debug(<span class="string">'todo save into local success!'</span>)</div><div class="line"></div><div class="line"><span class="meta">    @staticmethod</span></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_thread_job_2</span><span class="params">()</span>:</span></div><div class="line">        <span class="comment"># job3 will open local todo file and execute method inside it</span></div><div class="line"></div><div class="line">        <span class="keyword">if</span> os.path.exists(<span class="string">'todo.pkl'</span>):</div><div class="line">            <span class="keyword">with</span> open(<span class="string">'todo.pkl'</span>, <span class="string">'rb'</span>) <span class="keyword">as</span> f:</div><div class="line">                obj = pickle.load(f)</div><div class="line">            class_name = obj[<span class="string">'class_name'</span>]</div><div class="line">            function_name = obj[<span class="string">'function_name'</span>]</div><div class="line">            function_args = obj[<span class="string">'function_args'</span>]</div><div class="line"></div><div class="line">            c = globals()[class_name]()</div><div class="line">            func = getattr(c, function_name)</div><div class="line">            print(func)</div><div class="line">            func(*function_args)</div><div class="line">            logging.debug(<span class="string">'resume function execute succeed!'</span>)</div><div class="line">        <span class="keyword">else</span>:</div><div class="line">            logging.debug(<span class="string">'file not find.'</span>)</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></div><div class="line">    cruise_bot = CruiseBot()</div><div class="line">    cruise_bot.cruise()</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    main()</div></pre></td></tr></table></figure>
<p>这里我们的ToDoer这个类在module <code>todo/todo.py</code>这个文件中，我们实现import进去，那么我用global这个反射就可以根据类的名字还原成类的对象，今儿找到我们需要的方法在执行它。另外参数的问题也可以轻而易举的搞定。</p>
<p>输出如下：</p>
<figure class="highlight smali"><table><tr><td class="code"><pre><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:00.268181</div><div class="line">delta  5</div><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:05.270000</div><div class="line">delta  10</div><div class="line">(MainThread) start<span class="built_in"> execute </span>job 2</div><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:10.274169</div><div class="line">(bob       ) todo save into local success!</div><div class="line">delta  15</div><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:15.274941</div><div class="line">delta  20</div><div class="line">(MainThread) start<span class="built_in"> execute </span>job 2</div><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:20.278646</div><div class="line">&lt;function ToDoer.todo_job at 0x10b36f400&gt;</div><div class="line">['hello', 'fuck', 'shit', 'man']</div><div class="line">I am executed!!!!!!!</div><div class="line">(cc        ) resume function<span class="built_in"> execute </span>succeed!</div><div class="line">delta  25</div><div class="line">(MainThread) Cruise, now time is: 2017-04-28 14:43:25.284144</div><div class="line">delta  30</div></pre></td></tr></table></figure>
<p>好了，本次列车到此结束，欢迎下次乘坐。</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-2017-3-26-ubuntu云服务器无法访问https折腾"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
    <div class="article-meta">
      
	<a href="/2017/04/14/2017-3-26-ubuntu云服务器无法访问https折腾/" class="article-date">
	  <time datetime="2017-04-14T14:54:38.000Z" itemprop="datePublished">2017-04-14</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="ubuntu云服务器无法访问https折腾"><a href="#ubuntu云服务器无法访问https折腾" class="headerlink" title="ubuntu云服务器无法访问https折腾"></a>ubuntu云服务器无法访问https折腾</h1><p>这是一个很蛋疼的过程，一开始还以为是什么鬼问题，配置也配置了就是不行，我日，最后发现是iptables的问题，果然服务器的防火墙很吊，既然这个iptables这么难搞那我们今天就好好高一下这个iptables。</p>
<h2 id="ubuntu云服务器开启iptables的https"><a href="#ubuntu云服务器开启iptables的https" class="headerlink" title="ubuntu云服务器开启iptables的https"></a>ubuntu云服务器开启iptables的https</h2><ul>
<li><p>开启https</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><div class="line">sudo iptables -A INPUT -<span class="selector-tag">p</span> tcp --dport <span class="number">443</span> -j ACCEPT</div></pre></td></tr></table></figure>
</li>
<li><p>开启ssh，http</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><div class="line">sudo iptables -A INPUT -<span class="selector-tag">p</span> tcp --dport <span class="number">22</span> -j ACCEPT </div><div class="line">sudo iptables -A INPUT -<span class="selector-tag">p</span> tcp --dport <span class="number">80</span> -j ACCEPT</div></pre></td></tr></table></figure>
</li>
</ul>
<p>参数说明：<br><code>-A INPUT</code>: 表示追加一条规则到INPUT这个chain中，chain就是规则连。</p>
<p>那么还有一个很蛋疼的地方就是，不仅仅是APPEND还要制定添加到某个位置，怎么搞呢？</p>
<ul>
<li>添加到指定位置<figure class="highlight lsl"><table><tr><td class="code"><pre><div class="line">sudo iptables -I INPUT <span class="number">4</span> -p tcp --dport <span class="number">33</span> -j ACCEPT</div></pre></td></tr></table></figure>
</li>
</ul>
<p>看简单，只需要把-A改成-I，然后在要添加的chain后面加上index的即可。<br>让我们看看修改之后和是不是尼吗可以访问了我草。<br>其实道理是一样，这是增加规则，那么怎么查看iptables里面现有的规则呢？</p>
<h2 id="ubuntu云服务器查看iptables入站规则"><a href="#ubuntu云服务器查看iptables入站规则" class="headerlink" title="ubuntu云服务器查看iptables入站规则"></a>ubuntu云服务器查看iptables入站规则</h2><figure class="highlight ada"><table><tr><td class="code"><pre><div class="line">sudo iptables -L -n <span class="comment">--line-numbers</span></div></pre></td></tr></table></figure>
<p>shit， tmux复制不了输出信息，大家脑部一下吧。</p>
<h2 id="删除iptables规则"><a href="#删除iptables规则" class="headerlink" title="删除iptables规则"></a>删除iptables规则</h2><p>当然新加入了规则也是可以删除的，首先查看iptables规则对应的行号：<br><figure class="highlight ada"><table><tr><td class="code"><pre><div class="line">sudo iptables -L -n <span class="comment">--line-numbers</span></div></pre></td></tr></table></figure></p>
<p>然后删除之：<br><figure class="highlight arduino"><table><tr><td class="code"><pre><div class="line">sudo iptables -D <span class="literal">INPUT</span> <span class="number">2</span></div></pre></td></tr></table></figure></p>
<h2 id="保存并重启iptables"><a href="#保存并重启iptables" class="headerlink" title="保存并重启iptables"></a>保存并重启iptables</h2><p>其实也不叫做重启，新加入了规则之后记得保存和重启，要不然不会有效果：<br><figure class="highlight ebnf"><table><tr><td class="code"><pre><div class="line"><span class="attribute">sudo iptables-save</span></div></pre></td></tr></table></figure></p>
<p>注意，这样保存只是在本次登录时保存，服务器重启之后和又会被清空，因此我们还需要保存为一个文本文件，并且，在网络启动的时候自动添加我们的防火墙规则：<br><figure class="highlight gradle"><table><tr><td class="code"><pre><div class="line">su root</div><div class="line"># must under root <span class="keyword">do</span> <span class="keyword">this</span></div><div class="line">sudo iptables-save &gt; <span class="regexp">/etc/i</span>ptables.up.rules</div></pre></td></tr></table></figure></p>
<p> 然后，给/etc/network/interfaces，添加最后和一行：<br> <figure class="highlight stylus"><table><tr><td class="code"><pre><div class="line">pre-up iptables-restore &lt; /etc/iptables<span class="selector-class">.up</span><span class="selector-class">.rules</span></div></pre></td></tr></table></figure></p>
<p> OK，蛋疼的iptables到此为止！！！</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-2017-3-26-腾讯云服务器部署https全记录"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
    <div class="article-meta">
      
	<a href="/2017/04/14/2017-3-26-腾讯云服务器部署https全记录/" class="article-date">
	  <time datetime="2017-04-14T14:54:38.000Z" itemprop="datePublished">2017-04-14</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="腾讯云服务器部署https全记录"><a href="#腾讯云服务器部署https全记录" class="headerlink" title="腾讯云服务器部署https全记录"></a>腾讯云服务器部署https全记录</h1><p>终于吧云上的https给部署上去了，折腾了很久，除了下载ssl证书到服务器，配置一下nginx，其他的也没有什么难的地方，最后卡在防火墙这里，不知道哪里出问题了，关于防火墙全面破解我已经写了一个教程，应该问题不大，为了防止后面忘记还是记录梳理一下云服务器部署https的过程吧。</p>
<h2 id="首先https请获取到ssl证书"><a href="#首先https请获取到ssl证书" class="headerlink" title="首先https请获取到ssl证书"></a>首先https请获取到ssl证书</h2><p>ssl证书怎么获取我不用本地的方法，还是直接向云服务器提供商获取吧，然后下载证书，一般是两个文件，比如：<br><figure class="highlight stylus"><table><tr><td class="code"><pre><div class="line"><span class="number">1</span>_lewisjin<span class="selector-class">.xyz_bundle</span><span class="selector-class">.crt</span></div><div class="line"><span class="number">2</span>_lewisjin<span class="selector-class">.xyz</span><span class="selector-class">.key</span></div></pre></td></tr></table></figure></p>
<p>两个文件，接下来把这两个文件解压到目录：<br><figure class="highlight awk"><table><tr><td class="code"><pre><div class="line"><span class="regexp">/etc/</span>nginx<span class="regexp">/conf.d/</span></div></pre></td></tr></table></figure></p>
<p>我比较习惯用这个目录，其实哪里都无所谓，只要保证nginx可以有读取的权限就可以。然后，接下来会有两个地方用到它，一个是gunicorn，一个是nginx。</p>
<h2 id="给gunicorn配置证书"><a href="#给gunicorn配置证书" class="headerlink" title="给gunicorn配置证书"></a>给gunicorn配置证书</h2><p>我们先给gunicorn配置证书吧，直接这样：<br><figure class="highlight groovy"><table><tr><td class="code"><pre><div class="line">[<span class="string">program:</span>oumenglite_supervisor]</div><div class="line">command=<span class="regexp">/usr/</span>local<span class="regexp">/bin/</span>gunicorn --certfile=<span class="regexp">/etc/</span>nginx<span class="regexp">/conf.d/</span><span class="number">1</span>_lewisjin.xyz_bundle.crt --keyfile=<span class="regexp">/etc/</span>nginx<span class="regexp">/conf.d/</span><span class="number">2</span>_lewisjin.xyz.key --chdir <span class="regexp">/home/</span>ubuntu<span class="regexp">/WebSites/</span>oumenglite oumenglite.wsgi -b <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span>:<span class="number">8100</span>  -w <span class="number">3</span></div><div class="line">user=nobody</div><div class="line">autostart=<span class="literal">true</span></div><div class="line">autorestart=<span class="literal">true</span></div><div class="line">stdout_logfile=<span class="regexp">/home/</span>ubuntu<span class="regexp">/WebSites/</span>oumenglite<span class="regexp">/logs/</span>gunicorn_supervisor.log</div><div class="line">stderr_logfile=<span class="regexp">/home/</span>ubuntu<span class="regexp">/WebSites/</span>oumenglite<span class="regexp">/logs/</span>gunicorn_supervisor.log</div></pre></td></tr></table></figure></p>
<p>这也就ok。接着reread reload restart in supervisorctl中。</p>
<h2 id="给nginx配置证书"><a href="#给nginx配置证书" class="headerlink" title="给nginx配置证书"></a>给nginx配置证书</h2><p>其实一开始不懂的时候还是很方的，我直接贴贴配置文件吧：<br><figure class="highlight crmsh"><table><tr><td class="code"><pre><div class="line">server&#123;</div><div class="line">        listen <span class="number">80</span>;</div><div class="line">        listen [::]:<span class="number">80</span>;</div><div class="line">        server_name www.lewisjin.xyz;</div><div class="line">        return      <span class="number">301</span> https://$server_name$request_uri;</div><div class="line">&#125;</div><div class="line">server&#123;</div><div class="line">        listen <span class="number">80</span>;</div><div class="line">        listen [::]:<span class="number">80</span>;</div><div class="line">        server_name lewisjin.xyz;</div><div class="line">        return      <span class="number">301</span> https://$server_name$request_uri;</div><div class="line">&#125;</div><div class="line"></div><div class="line">server &#123;</div><div class="line">        listen <span class="number">443</span>;</div><div class="line">        listen [::]:<span class="number">443</span>;</div><div class="line"></div><div class="line">        server_name www.lewisjin.xyz;</div><div class="line"></div><div class="line">        charset utf-<span class="number">8</span>;</div><div class="line">        <span class="comment">#配置https ssl证书</span></div><div class="line">        ssl on;</div><div class="line">        ssl_certificate /etc/nginx/conf.d/<span class="number">1</span>_lewisjin.xyz_bundle.crt;</div><div class="line">        ssl_certificate_key /etc/nginx/conf.d/<span class="number">2</span>_lewisjin.xyz.key;</div><div class="line">        ssl_session_timeout <span class="number">5m</span>;</div><div class="line">        ssl_protocols TLSv1 TLSv1.<span class="number">1</span> TLSv1.<span class="number">2</span>; <span class="comment">#按照这个协议配置</span></div><div class="line">        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;<span class="comment">#按照这个套件配置</span></div><div class="line">        ssl_prefer_server_ciphers on;</div><div class="line"></div><div class="line">        <span class="comment">#root /var/www/html/;</span></div><div class="line">        <span class="comment">#index index.html;</span></div><div class="line"></div><div class="line">        <span class="comment"># let nginx parse url, and let all this urls</span></div><div class="line">        <span class="comment"># let gunicorn sovle them!</span></div><div class="line">        <span class="keyword">location</span> <span class="title">/ &#123;</span></div><div class="line">                # First attempt to serve request as file, then</div><div class="line">                <span class="comment"># as directory, then fall back to displaying a 404.</span></div><div class="line">                proxy_pass https://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">8100</span>;</div><div class="line">                try_files $uri $uri/ =<span class="number">404</span>;</div><div class="line">        &#125;</div><div class="line"></div><div class="line">        <span class="keyword">location</span> <span class="title">/admin</span>&#123;</div><div class="line">                proxy_pass https://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">8100</span>;</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">location</span> <span class="title">/about</span> &#123;</div><div class="line">                proxy_pass https://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">8100</span>;</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">location</span> <span class="title">/api</span>&#123;</div><div class="line">                proxy_pass https://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">8100</span>;</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">location</span> <span class="title">/static</span>/ &#123;</div><div class="line">                autoindex on;</div><div class="line">                alias /home/ubuntu/WebSites/oumenglite/collected_static/;</div><div class="line">         &#125;</div><div class="line">        <span class="keyword">location</span> <span class="title">/media</span>/ &#123;</div><div class="line">                alias /home/ubuntu/WebSites/oumenglite/media/;</div><div class="line">        &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>第一段是80端口转发443的代码，第二段是配置证书，当然除了监听www.lewisjin.xyz可能你还要监听lewisjin.xyz，这里简写了。<br>最后的最后蛋疼的是这里静态文件的路径千万别写错了啊，写错了就贵了。</p>
<h2 id="All-Done"><a href="#All-Done" class="headerlink" title="All Done!"></a>All Done!</h2>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-Python-多线程多并发完全整理"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/04/12/Python-多线程多并发完全整理/">Python 多线程多并发完全整理</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/04/12/Python-多线程多并发完全整理/" class="article-date">
	  <time datetime="2017-04-12T02:23:48.000Z" itemprop="datePublished">2017-04-12</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="Python多线程专辑"><a href="#Python多线程专辑" class="headerlink" title="Python多线程专辑"></a>Python多线程专辑</h1><blockquote>
<p>这篇我们专门研究一下python多线程，感觉越来越像程序员了卧槽，没有办法为了节约时间，磨刀不误砍菜工作啊，多线程掌握好了以后写程序处理东西可以节省大把的时间。</p>
</blockquote>
<h2 id="multiprocessing库"><a href="#multiprocessing库" class="headerlink" title="multiprocessing库"></a>multiprocessing库</h2><p>这是python里面的多线程处理库，这个是跨平台的，要实现多线程分为以下两种：</p>
<ul>
<li>多线程处理的函数没有返回值，只是让一个函数同时执行上百个，这个比如我定义一个函数现在不同url的图片，传入的url都是url，只不过url不同，因此可以写成一个函数，分好几百条线程下载；</li>
<li>多线程处理有返回值，这种情况我们不仅仅要分线程下载，还要收集下载返回的信息。比如我一个函数处理一行文本，比如对一句话把它进行分词，那么我需要收集分词之后的结果。</li>
</ul>
<p>针对这两种情况，基本上就这两种情况了，第一种用Process这个对象，第二种用Pool这个对象。这是根据我的实际经验来的。</p>
<h3 id="Process"><a href="#Process" class="headerlink" title="Process"></a>Process</h3><p>我们从简单要复杂，Pool相对于process要复杂一点，process就很简单了，我们跑一个代码看一下：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"></div><div class="line"><span class="keyword">import</span> multiprocessing <span class="keyword">as</span> mp</div><div class="line"><span class="keyword">import</span> time</div><div class="line"><span class="keyword">import</span> random</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">work</span><span class="params">(proc_id, sent)</span>:</span></div><div class="line">    print(<span class="string">'I am worker &#123;&#125;, my sentence is &#123;&#125;'</span>.format(proc_id, sent))</div><div class="line">    time.sleep(random.random() * <span class="number">20</span>)</div><div class="line">    print(<span class="string">'worker &#123;&#125; finished his job!'</span>.format(proc_id))</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    args = [(i, s) <span class="keyword">for</span> i, s <span class="keyword">in</span> enumerate([<span class="string">'shit'</span>, <span class="string">'fuck man'</span>, <span class="string">'go die'</span>, <span class="string">'cao ni ma'</span>])]</div><div class="line">    process = [mp.Process(target=work, args=i) <span class="keyword">for</span> i <span class="keyword">in</span> args]</div><div class="line">    <span class="keyword">for</span> p <span class="keyword">in</span> process:</div><div class="line">        p.start()</div><div class="line">    <span class="keyword">for</span> p <span class="keyword">in</span> process:</div><div class="line">        p.join()</div></pre></td></tr></table></figure>
<p>我们可以看到如下的输出：</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><div class="line">I <span class="keyword">am</span> worker <span class="number">0</span>, my sentence <span class="keyword">is</span> shit</div><div class="line">I <span class="keyword">am</span> worker <span class="number">1</span>, my sentence <span class="keyword">is</span> fuck man</div><div class="line">I <span class="keyword">am</span> worker <span class="number">2</span>, my sentence <span class="keyword">is</span> <span class="keyword">go</span> die</div><div class="line">I <span class="keyword">am</span> worker <span class="number">3</span>, my sentence <span class="keyword">is</span> cao ni <span class="keyword">ma</span></div><div class="line">worker <span class="number">1</span> finished <span class="keyword">his</span> job!</div><div class="line">worker <span class="number">2</span> finished <span class="keyword">his</span> job!</div><div class="line">worker <span class="number">3</span> finished <span class="keyword">his</span> job!</div><div class="line">worker <span class="number">0</span> finished <span class="keyword">his</span> job!</div></pre></td></tr></table></figure>
<p>这里我没有显示时间，实际上你运行会看到，不同的进程是在不同的时候完成的，也就是说每个work被单独调用了，因为中间的延时不同，这里Process里面的args传入的是一个tuple，也就是函数的参数。</p>
<h3 id="Pool"><a href="#Pool" class="headerlink" title="Pool"></a>Pool</h3><p>Pool相对来说就有点复杂，因为Pool可以收集返回的信息，也就是函数的返回值。但是Pool官方是不支持传入多个参数的，也就是说你只能给函数传入一个参数。但是我们有解决办法，有一个装饰器来解析函数参数。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">unpack_args</span><span class="params">(func)</span>:</span></div><div class="line">    <span class="keyword">from</span> functools <span class="keyword">import</span> wraps</div><div class="line"></div><div class="line"><span class="meta">    @wraps(func)</span></div><div class="line">    <span class="function"><span class="keyword">def</span> <span class="title">wrapper</span><span class="params">(args)</span>:</span></div><div class="line">        <span class="keyword">if</span> isinstance(args, dict):</div><div class="line">            <span class="keyword">return</span> func(**args)</div><div class="line">        <span class="keyword">else</span>:</div><div class="line">            <span class="keyword">return</span> func(*args)</div><div class="line">    <span class="keyword">return</span> wrapper</div><div class="line"></div><div class="line"></div><div class="line"><span class="meta">@unpack_args</span></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">worker</span><span class="params">(procnum, sent)</span>:</span></div><div class="line">    print(<span class="string">'I am number %d in process %d, the sent: %s'</span> % (procnum, os.getpid(), sent))</div><div class="line">    <span class="keyword">return</span> os.getpid() // <span class="number">2</span>, sent</div><div class="line"></div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line">    pool = multiprocessing.Pool(processes=<span class="number">4</span>)</div><div class="line">    sents = [<span class="string">'hello'</span>, <span class="string">'nihao'</span>, <span class="string">' shit man'</span>, <span class="string">'fuck wocao!!'</span>]</div><div class="line">    pro_nums = range(len(sents))</div><div class="line">    print(pool.map(worker, zip(pro_nums, sents)))</div></pre></td></tr></table></figure>
<p>我们运行可以看到：</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><div class="line">I <span class="keyword">am</span> <span class="keyword">number</span> <span class="number">0</span> in process <span class="number">75170</span>, the sen<span class="variable">t:</span> hello</div><div class="line">I <span class="keyword">am</span> <span class="keyword">number</span> <span class="number">1</span> in process <span class="number">75171</span>, the sen<span class="variable">t:</span> nihao</div><div class="line">I <span class="keyword">am</span> <span class="keyword">number</span> <span class="number">2</span> in process <span class="number">75172</span>, the sen<span class="variable">t:</span>  shit man</div><div class="line">I <span class="keyword">am</span> <span class="keyword">number</span> <span class="number">3</span> in process <span class="number">75173</span>, the sen<span class="variable">t:</span> fuck wocao!!</div><div class="line">[(<span class="number">37585</span>, <span class="string">'hello'</span>), (<span class="number">37585</span>, <span class="string">'nihao'</span>), (<span class="number">37586</span>, <span class="string">' shit man'</span>), (<span class="number">37586</span>, <span class="string">'fuck wocao!!'</span>)]</div></pre></td></tr></table></figure>
<p>线程被异步调用了，而且返回值是按照顺序返回的，屌把，也就是说Pool内部帮我们做了很多事情，比如多线程的调度，任务等待等，只要给定多少个线程，把所有要做的事情传给Pool，它就可以按照顺序返回给我们相应的值，以多线程的高速度，这很Pythonic！！！</p>
<h1 id="One-More-Thing"><a href="#One-More-Thing" class="headerlink" title="One More Thing"></a>One More Thing</h1><p>这个多线程基本上就这些东西了，要深入也可以但是没有必要掌握这两个，你的代码效率可以提升几十倍。最后我不得不说我的聊天机器人要赶紧做出来卧槽，没有时间了。</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-RNN-Series-Return-LSTM时间序列预测翻新文章，这次我们走的更远更专业"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/04/11/RNN-Series-Return-LSTM时间序列预测翻新文章，这次我们走的更远更专业/">RNN Series Return LSTM时间序列预测翻新文章，这次我们走的更远更专业</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/04/11/RNN-Series-Return-LSTM时间序列预测翻新文章，这次我们走的更远更专业/" class="article-date">
	  <time datetime="2017-04-11T08:35:08.000Z" itemprop="datePublished">2017-04-11</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <blockquote>
<p>一直以来都在研究深度学习的东西，这几周重新拾起来时间序列进行研究，这次研究将是长期和专业的，我们将从学术的角度对问题进行剖析，同时接下来我会把所有实现的模型在论文完成之后开源所有代码，供大家参考。</p>
</blockquote>
<h1 id="Preface"><a href="#Preface" class="headerlink" title="Preface"></a>Preface</h1><p>此前<a href="http://www.jianshu.com/p/5d6d5aac4dbd" target="_blank" rel="noopener">做了一篇文章</a>，也是关于LSTM时间序列预测，经过将近半年的改变和进化，我再次提笔写下这篇关于时间序列的文章。算是和前文的一个对比把，也是近期对时间序列进行深度科研的一个开始。前端时间经历了深度学习从入门到放弃的漫长过程，在成长也在蜕变，经历了滴滴实习期间做图像相关工作再到最近摸索的自然语言处理，最后为了完成毕业论文而做的时序分析，所有的一切都在漫不经心的变化着。如果大家对我近期的NLP相关工作感兴趣可以star一下我近期开源的几个项目，其中有个作诗机器人大家应该会喜欢： <a href="https://github.com/jinfagang/tensorflow_poems.git" target="_blank" rel="noopener">GitHub 传送门</a>.<br>闲话不多说，让我们直接开始这篇文章的正题。</p>
<h1 id="Time-Series"><a href="#Time-Series" class="headerlink" title="Time Series"></a>Time Series</h1><p>时间序列预测是一个很常见的问题，不同于传统方法，深度学习在时间序列预测上的有效性一直没有得到认可，我最近的工作就是要证明它，用深度学习的方法比传统方法好上千倍。<br>首先我们还是用上一篇文章使用的passenger数据来进行操作把。<br>上前后对比照先：</p>
<p><img src="http://upload-images.jianshu.io/upload_images/617746-b1432f7c8e607d86.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="previous"></p>
<p><img src="http://ofwzcunzi.bkt.clouddn.com/eefICtQXTlU1QDXf.png" alt="after"></p>
<p>这次依旧是处理passenger数据，数据可以在我的原来的github repo中找到，新版本的额代码可能在稍后开源，开源设置自定义补长，你几乎不需要考虑输入数据问题，只要把原始数据喂入模型，新的代码可以自动处理，包括步长操作，分batch，甚至可以自定义是否归一化，分分钟可以对比归一化前后的差别。<br>贴个训练图片：</p>
<p><img src="http://ofwzcunzi.bkt.clouddn.com/vpMFCYyTlqMgD4Xt.png" alt="PicName"></p>
<h1 id="River-Flow-data"><a href="#River-Flow-data" class="headerlink" title="River Flow data"></a>River Flow data</h1><p>实际上我这次打算用这个数据集来说明问题：</p>
<figure class="highlight lsl"><table><tr><td class="code"><pre><div class="line"><span class="string">"Month"</span>,<span class="string">"Monthly riverflow in cms"</span></div><div class="line"><span class="string">"1923-01"</span>,<span class="number">10.251</span></div><div class="line"><span class="string">"1923-02"</span>,<span class="number">11.129</span></div><div class="line"><span class="string">"1923-03"</span>,<span class="number">11.582</span></div><div class="line"><span class="string">"1923-04"</span>,<span class="number">11.327</span></div><div class="line"><span class="string">"1923-05"</span>,<span class="number">10.760</span></div><div class="line"><span class="string">"1923-06"</span>,<span class="number">10.477</span></div><div class="line"><span class="string">"1923-07"</span>,<span class="number">11.610</span></div><div class="line"><span class="string">"1923-08"</span>,<span class="number">19.284</span></div><div class="line"><span class="string">"1923-09"</span>,<span class="number">22.002</span></div><div class="line"><span class="string">"1923-10"</span>,<span class="number">14.243</span></div><div class="line"><span class="string">"1923-11"</span>,<span class="number">12.176</span></div><div class="line"><span class="string">"1923-12"</span>,<span class="number">11.440</span></div><div class="line"><span class="string">"1924-01"</span>,<span class="number">10.902</span></div><div class="line"><span class="string">"1924-02"</span>,<span class="number">10.392</span></div><div class="line"><span class="string">"1924-03"</span>,<span class="number">11.836</span></div><div class="line"><span class="string">"1924-04"</span>,<span class="number">9.996</span></div><div class="line"><span class="string">"1924-05"</span>,<span class="number">9.401</span></div><div class="line"><span class="string">"1924-06"</span>,<span class="number">11.242</span></div><div class="line"><span class="string">"1924-07"</span>,<span class="number">13.989</span></div><div class="line"><span class="string">"1924-08"</span>,<span class="number">17.160</span></div><div class="line"><span class="string">"1924-09"</span>,<span class="number">12.318</span></div><div class="line"><span class="string">"1924-10"</span>,<span class="number">11.185</span></div></pre></td></tr></table></figure>
<p>这是河流水流量随时间变化的序列，很明显这个跟时间有关，大家可以看看这个震荡多厉害：</p>
<p><img src="http://ofwzcunzi.bkt.clouddn.com/Gss7XyKowI8YCQ7h.png" alt="PicName"></p>
<p>但同时也可以看到，预测值也就是橙色的值，预测的非常好，因为这里我使用了深层的LSTM的进行预测。接下来会有更多模型调优的过程。</p>
<h1 id="Future-Work"><a href="#Future-Work" class="headerlink" title="Future Work"></a>Future Work</h1><p>由于整个项目还在进行之中，所以大家想一起交流时间序列研究的可以添加我的微信 : <code>jintianiloveu</code>，我们有个讨论群，大家可以交流模型，看法，甚至可以延伸到文本领域进行扩展。<br>接下来我要做的工作将要对标几个数据集的精确度，做benchmark， 文本生成领域的VAE非监督模型我也将继承进来，论文完成之后所有代码都将开源给大家参考。</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-Pytorch-从入门到放弃之一"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/04/10/Pytorch-从入门到放弃之一/">Pytorch 从入门到放弃之一</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/04/10/Pytorch-从入门到放弃之一/" class="article-date">
	  <time datetime="2017-04-10T02:00:30.000Z" itemprop="datePublished">2017-04-10</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p>Pytorch 踩坑手记。<br>
        <!-- Pytorch 踩坑手记。
Pytorch install开始填坑了，为什么要从tensorflow转移到pytorch？我思考了一下，tensorflow现在越来越笨重了，而且内存占用太大，虽然玩的人多，但是却一直感觉会被谷歌垄断起来，最近谷歌居然开设tensorflow学习班更是让我感觉反感，这鸡巴就是赤裸裸的用框架赚钱啊，虽然谷歌不稀罕这点钱，但是最起码的增加了我们从业人员的竞争对手，......  -->
        <p class="article-more-link">
          <a href="/2017/04/10/Pytorch-从入门到放弃之一/#more">阅读全文</a>
        </p>
      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  
    <article id="post-树莓派开启Docker时代-HypriotOS搭载黑珍珠号开启新的航程"  class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" itemprop="name">
      <a class="article-title" href="/2017/04/06/树莓派开启Docker时代-HypriotOS搭载黑珍珠号开启新的航程/">树莓派开启Docker时代--HypriotOS搭载黑珍珠号开启新的航程</a>
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2017/04/06/树莓派开启Docker时代-HypriotOS搭载黑珍珠号开启新的航程/" class="article-date">
	  <time datetime="2017-04-06T11:00:10.000Z" itemprop="datePublished">2017-04-06</time>
	</a>

      
      
    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="HypriotOS安装"><a href="#HypriotOS安装" class="headerlink" title="HypriotOS安装"></a>HypriotOS安装</h2><p>首先必须吐槽一下，树莓派build opencv根本没法完成，依赖缺胳膊少腿，开始转向Docker了，用别人搭建好的容器来搞。二话不说我们找到了这个HypriotOS，名字绕口，暂且叫做黑珍珠号。它自带的Docker就是Black Pearl。我们来看看咋下载：</p>
<figure class="highlight livecodeserver"><table><tr><td class="code"><pre><div class="line"><span class="keyword">http</span>://blog.hypriot.com/getting-started-<span class="keyword">with</span>-docker-<span class="keyword">on</span>-your-arm-device/</div></pre></td></tr></table></figure>
<p>这个博客可以下载，在flash的时候其实可以设置把你的用户名和wifi ssid psk烧入进去，不过直接flash然后命令行链接wifi也是可以的。</p>
<h2 id="Docker从入门到精通"><a href="#Docker从入门到精通" class="headerlink" title="Docker从入门到精通"></a>Docker从入门到精通</h2><p>重点是我们来看看Docker是一个怎么强大的云工具。我们在树莓派上运行一个云端的docker服务：<br><figure class="highlight dockerfile"><table><tr><td class="code"><pre><div class="line">docker <span class="keyword">run</span><span class="bash"> <span class="_">-d</span> -p 80:80 hypriot/rpi-busybox-httpd</span></div></pre></td></tr></table></figure></p>
<p>这个镜像1m，可以看到：</p>
<figure class="highlight groovy"><table><tr><td class="code"><pre><div class="line">HypriotOS/<span class="string">armv7:</span> pirate<span class="meta">@black</span>-pearl <span class="keyword">in</span> ~</div><div class="line">$ docker run -d -p <span class="number">80</span>:<span class="number">80</span> hypriot/rpi-busybox-httpd</div><div class="line">Unable to find image <span class="string">'hypriot/rpi-busybox-httpd:latest'</span> locally</div><div class="line"><span class="string">latest:</span> Pulling from hypriot/rpi-busybox-httpd</div><div class="line"><span class="string">c74a9c6a645f:</span> Pull complete</div><div class="line"><span class="number">6</span><span class="string">f1938f6d8ae:</span> Pull complete</div><div class="line"><span class="string">e1347d4747a6:</span> Pull complete</div><div class="line"><span class="string">a3ed95caeb02:</span> Pull complete</div><div class="line"><span class="string">Digest:</span> <span class="string">sha256:</span>c00342f952d97628bf5dda457d3b409c37df687c859df82b9424f61264f54cd1</div><div class="line"><span class="string">Status:</span> Downloaded newer image <span class="keyword">for</span> hypriot/rpi-busybox-<span class="string">httpd:</span>latest</div><div class="line"><span class="number">52291</span>df45f9d165bb284d62f3a54497fb7c1b1de601ca306fb4970dbbe391629</div></pre></td></tr></table></figure>
<p>这个时候我们牛逼的镜像就pull下来了，然后怎么看呢？</p>
<figure class="highlight elixir"><table><tr><td class="code"><pre><div class="line">HypriotOS/<span class="symbol">armv7:</span> pirate<span class="variable">@black</span>-pearl <span class="keyword">in</span> ~</div><div class="line"><span class="variable">$ </span>docker ps</div><div class="line">CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                NAMES</div><div class="line"><span class="number">52291</span>df45f9d        hypriot/rpi-busybox-httpd   <span class="string">"/bin/busybox http..."</span>   <span class="number">38</span> seconds ago      Up <span class="number">15</span> seconds       <span class="number">0</span>.<span class="number">0</span>.<span class="number">0</span>.<span class="number">0</span><span class="symbol">:</span><span class="number">80</span>-&gt;<span class="number">80</span>/tcp   quirky_goldwasser</div></pre></td></tr></table></figure>
<p>看到没，牛逼把，卧槽！！！这个时候我们在浏览器上输入树莓派的ip，应该就能访问树莓派的80端口查看那个服务了：<br>![PicName](<a href="http://ofwzcunzi.bkt.clouddn.com/IWHKpIKqFgih17YG.png）" target="_blank" rel="noopener">http://ofwzcunzi.bkt.clouddn.com/IWHKpIKqFgih17YG.png）</a><br>树莓派Armed Docker！！！！</p>
<h2 id="OpenCV编你妹，老子直接从docker拉一个镜像下来行么？"><a href="#OpenCV编你妹，老子直接从docker拉一个镜像下来行么？" class="headerlink" title="OpenCV编你妹，老子直接从docker拉一个镜像下来行么？"></a>OpenCV编你妹，老子直接从docker拉一个镜像下来行么？</h2><p>让我们来探索一下把。懒得编译了，直接从docker拉。拉个鸡毛，拉镜像也不行。我们总结一个使用树莓派的最佳姿势把。</p>
<h1 id="使用树莓派的最佳姿势"><a href="#使用树莓派的最佳姿势" class="headerlink" title="使用树莓派的最佳姿势"></a>使用树莓派的最佳姿势</h1><p>[UPDATE] 经过再三是错，还是这个方法可行</p>
<figure class="highlight vala"><table><tr><td class="code"><pre><div class="line"><span class="meta"># 先安装jessie with pixel</span></div><div class="line"><span class="meta"># 在安装docker</span></div><div class="line"></div><div class="line">curl -s https:<span class="comment">//packagecloud.io/install/repositories/Hypriot/Schatzkiste/script.deb.sh | sudo bash</span></div><div class="line">sudo apt-<span class="keyword">get</span> install docker-hypriot=<span class="number">1.10</span><span class="number">.3</span><span class="number">-1</span></div><div class="line">sudo sh -c <span class="string">'usermod -aG docker $SUDO_USER'</span></div><div class="line">sudo systemctl enable docker.service</div><div class="line">sudo docker info</div><div class="line"><span class="meta"># 最后测试一下</span></div><div class="line">docker run -d -p <span class="number">80</span>:<span class="number">80</span> hypriot/rpi-busybox-httpd</div></pre></td></tr></table></figure>
<h2 id="首先安装HypriotOS"><a href="#首先安装HypriotOS" class="headerlink" title="首先安装HypriotOS"></a>首先安装HypriotOS</h2><p>去到<a href="http://blog.hypriot.com" target="_blank" rel="noopener">官网</a>下载镜像这个os包含了所有docker环境，所有东西都是为了docker而设置的。我们只要flash进去，第一次进入命令行环境，链接wifi，获取ip，然后链接即可。</p>
<h2 id="安装X-server"><a href="#安装X-server" class="headerlink" title="安装X server"></a>安装X server</h2><p>给HypriotOS安装图形界面。直接用这个<a href="https://github.com/hypriot/x11-on-HypriotOS.git" target="_blank" rel="noopener">github repo
</a> 介绍的东西。</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><div class="line">curl -sSL http<span class="variable">s:</span>//github.<span class="keyword">com</span>/hypriot/x11-<span class="keyword">on</span>-HypriotOS/raw/master/install-x11-basics.<span class="keyword">sh</span> | bash</div></pre></td></tr></table></figure>
<p>这大概需要十分钟。</p>

      
    </div>
    <footer class="article-footer">
      
      
      
    </footer>
  </div>
  
</article>

<!-- Table of Contents -->

  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/3/">&laquo; 上一页</a><a class="page-number" href="/">1</a><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><a class="page-number" href="/page/6/">6</a><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" href="/page/5/">下一页 &raquo;</a>
  </nav>

</section>
        
      </div>
      
        <div align="center" style="margin-top: 30px;"><hr class="hr" style="margin:0px; height:3px;"></div>
      
      <footer id="footer">
  

  <div class="container">
      	<div class="row">
	      <p> Powered by <a href="http://www.luoli-luoli.com/" target="_blank">萝莉萝莉</a> and <a href="http://www.luoli-luoli.com/sia" target="_blank">Sia</a> </p>
	      <p id="copyRightEn">Copyright &copy; 2017 - 2018 Jin Tian All Rights Reserved.</p>
	      
	      
    		<p class="busuanzi_uv">
				访客数 : <span id="busuanzi_value_site_uv"></span> |  
				访问量 : <span id="busuanzi_value_site_pv"></span>
		    </p>
  		   
		</div>

		
  </div>
</footer>


<!-- min height -->

<script>
    var wrapdiv = document.getElementById("wrap");
    var contentdiv = document.getElementById("content");
    var allheader = document.getElementById("allheader");

    wrapdiv.style.minHeight = document.body.offsetHeight + "px";
    if (allheader != null) {
      contentdiv.style.minHeight = document.body.offsetHeight - allheader.offsetHeight - document.getElementById("footer").offsetHeight + "px";
    } else {
      contentdiv.style.minHeight = document.body.offsetHeight - document.getElementById("footer").offsetHeight + "px";
    }
</script>
    </div>
    <!-- <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/categories" class="mobile-nav-link">Categories</a>
  
    <a href="/tags" class="mobile-nav-link">Tags</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
    <a href="http://luoli-luoli.com/chat" class="mobile-nav-link">Chat</a>
  
</nav> -->
    

<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/scripts.js"></script>


  <script src="/js/home.js"></script>










	<div style="display: none;">
    <script src="https://s95.cnzz.com/z_stat.php?id=1260716016&web_id=1260716016" language="JavaScript"></script>
  </div>



	<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
	</script>






  </div>

  <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h2 class="modal-title" id="myModalLabel">设置</h2>
      </div>
      <hr style="margin-top:0px; margin-bottom:0px; width:80%; border-top: 3px solid #000;">
      <hr style="margin-top:2px; margin-bottom:0px; width:80%; border-top: 1px solid #000;">


      <div class="modal-body">
          <div style="margin:6px;">
            <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" onclick="javascript:setFontSize();" aria-expanded="true" aria-controls="collapseOne">
              正文字号大小
            </a>
          </div>
          <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
          <div class="panel-body">
            您已调整页面字体大小
          </div>
        </div>
      


          <div style="margin:6px;">
            <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" onclick="javascript:setBackground();" aria-expanded="true" aria-controls="collapseTwo">
              夜间护眼模式
            </a>
        </div>
          <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
          <div class="panel-body">
            夜间模式已经开启，再次单击按钮即可关闭 
          </div>
        </div>

        <div>
            <a data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="true" aria-controls="collapseThree">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关 于&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a>
        </div>
         <div id="collapseThree" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree">
          <div class="panel-body">
            Jin Tian
          </div>
          <div class="panel-body">
            Copyright © 2018 Jintian All Rights Reserved.
          </div>
        </div>
      </div>


      <hr style="margin-top:0px; margin-bottom:0px; width:80%; border-top: 1px solid #000;">
      <hr style="margin-top:2px; margin-bottom:0px; width:80%; border-top: 3px solid #000;">
      <div class="modal-footer">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
      </div>
    </div>
  </div>
</div>
  
  <a id="rocket" href="#top" class=""></a>
  <script type="text/javascript" src="/js/totop.js?v=1.0.0" async=""></script>
  
</body>
</html>